////////////////////////////////////////////////////////////
/// Constructor
////////////////////////////////////////////////////////////
template <typename T>
Pool<T>::Pool( unsigned _uPoolSize ) :
    m_uNumAvailableElements( _uPoolSize )
{
    for ( unsigned i = 0; i < _uPoolSize; ++i ) {
        m_PoolElements.push_back( new T() );
    }
}

////////////////////////////////////////////////////////////
/// Destructor
////////////////////////////////////////////////////////////
template <typename T>
Pool<T>::~Pool() {
    for ( td_PoolList::iterator it = m_PoolElements.begin();
        it != m_PoolElements.end();
        ++it ) {
        delete (*it);
    }
    m_PoolElements.clear();
}

////////////////////////////////////////////////////////////
/// Return the next available element
////////////////////////////////////////////////////////////
template <typename T>
T* Pool<T>::Next() {
    T* pNext = NULL;

    if ( 0 == m_uNumAvailableElements ) {
        pNext           = new T();
    } else {
        pNext           = m_PoolElements.front();
        m_PoolElements.pop_front();
        --m_uNumAvailableElements;
    }
    
    m_PoolElements.push_back( pNext );

    return pNext;
}

////////////////////////////////////////////////////////////
/// Push back a newly available element
////////////////////////////////////////////////////////////
template <typename T>
void Pool<T>::Release( T* _pToFree ) {
    m_PoolElements.remove( _pToFree );
    m_PoolElements.push_front( _pToFree );
    ++m_uNumAvailableElements;
}

////////////////////////////////////////////////////////////
/// Push back all elements as available
////////////////////////////////////////////////////////////
template <typename T>
void Pool<T>::ReleaseAll() {
    m_uNumAvailableElements = m_PoolElements.size();
}